import { PermissionAction } from '@supabase/shared-types/out/constants' import { IS_PLATFORM, useFlag, useParams } from 'common' import { ChevronDown } from 'lucide-react' import { cloneElement, useState } from 'react' import { toast } from 'sonner' import { Alert, Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from 'ui' import { GenericSkeletonLoader } from 'ui-patterns' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { LogDrainDestinationSheetForm } from '@/components/interfaces/LogDrains/LogDrainDestinationSheetForm' import { LogDrains } from '@/components/interfaces/LogDrains/LogDrains' import { LOG_DRAIN_TYPES, LogDrainType, } from '@/components/interfaces/LogDrains/LogDrains.constants' import DefaultLayout from '@/components/layouts/DefaultLayout' import { PageLayout } from '@/components/layouts/PageLayout/PageLayout' import SettingsLayout from '@/components/layouts/ProjectSettingsLayout/SettingsLayout' import { ScaffoldContainer, ScaffoldSection } from '@/components/layouts/Scaffold' import { DocsButton } from '@/components/ui/DocsButton' import { LogDrainCreateVariables, useCreateLogDrainMutation, } from '@/data/log-drains/create-log-drain-mutation' import { LogDrainData, useLogDrainsQuery } from '@/data/log-drains/log-drains-query' import { useUpdateLogDrainMutation } from '@/data/log-drains/update-log-drain-mutation' import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { DOCS_URL } from '@/lib/constants' import type { NextPageWithLayout } from '@/types' const LogDrainsSettings: NextPageWithLayout = () => { const { can: canManageLogDrains, isLoading: isLoadingPermissions } = useAsyncCheckPermissions( PermissionAction.ANALYTICS_ADMIN_WRITE, 'logflare' ) const [open, setOpen] = useState(false) const { ref } = useParams() as { ref: string } const [selectedLogDrain, setSelectedLogDrain] = useState | null>(null) const [isCreateConfirmModalOpen, setIsCreateConfirmModalOpen] = useState(false) const [pendingLogDrainValues, setPendingLogDrainValues] = useState(null) const [mode, setMode] = useState<'create' | 'update'>('create') const { hasAccess: hasAccessToLogDrains, isLoading: isLoadingEntitlement } = useCheckEntitlements('log_drains') const sentryEnabled = useFlag('SentryLogDrain') const s3Enabled = useFlag('S3logdrain') const axiomEnabled = useFlag('axiomLogDrain') const otlpEnabled = useFlag('otlpLogDrain') const last9Enabled = useFlag('Last9LogDrain') const syslogEnabled = useFlag('syslogLogDrain') const { data: logDrains } = useLogDrainsQuery( { ref }, { enabled: !isLoadingEntitlement && hasAccessToLogDrains } ) const { mutate: createLogDrain, isPending: createLoading } = useCreateLogDrainMutation({ onSuccess: () => { toast.success('Log drain destination created') setIsCreateConfirmModalOpen(false) setOpen(false) }, onError: () => { toast.error('Failed to create log drain') setIsCreateConfirmModalOpen(false) setOpen(false) }, }) const { mutate: updateLogDrain, isPending: updateLoading } = useUpdateLogDrainMutation({ onSuccess: () => { toast.success('Log drain updated') setOpen(false) }, onError: () => { setOpen(false) toast.error('Failed to update log drain') }, }) const isLoading = createLoading || updateLoading function handleUpdateClick(drain: LogDrainData) { setSelectedLogDrain(drain) setMode('update') setOpen(true) } function handleNewClick(src: LogDrainType) { setSelectedLogDrain({ type: src }) setMode('create') setOpen(true) } const content = ( { if (!v) { setSelectedLogDrain(null) } setOpen(v) }} defaultValues={{ ...selectedLogDrain, type: selectedLogDrain?.type ? selectedLogDrain.type : 'webhook', }} isLoading={isLoading} onSubmit={({ name, description, type, ...values }) => { const logDrainValues = { name, description: description || '', type, config: values as any, // TODO: fix generated API types from backend id: selectedLogDrain?.id, projectRef: ref, token: selectedLogDrain?.token, } if (mode === 'create') { setPendingLogDrainValues(logDrainValues) setIsCreateConfirmModalOpen(true) } else { if (!logDrainValues.id || !selectedLogDrain?.token) { throw new Error('Log drain ID and token is required') } else { updateLogDrain(logDrainValues) } } }} /> {isLoadingPermissions ? ( ) : !canManageLogDrains ? ( You do not have permission to manage log drains ) : ( )} { if (pendingLogDrainValues) { createLogDrain(pendingLogDrainValues) setPendingLogDrainValues(null) } setIsCreateConfirmModalOpen(false) }} onCancel={() => { setIsCreateConfirmModalOpen(false) setPendingLogDrainValues(null) }} >

You are about to create a new log drain destination:{' '} {pendingLogDrainValues?.name}

{IS_PLATFORM && (

This will incur an additional $60 per month{' '} charge to your subscription.

)}

Are you sure you want to proceed?

) // [kemal]: Ordinarily would be bundled with the getLayout function below, however in this case we need access to some bits for the "Add destination" button to render as part of the in-built page header in . if (!isLoadingEntitlement && hasAccessToLogDrains) { return ( {!(logDrains?.length === 0) && (
)} } secondaryActions={} > {content}
) } return content } LogDrainsSettings.getLayout = (page) => ( {page} ) export default LogDrainsSettings